package com.cysyz.mylib.pdf.impl;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import com.cysyz.mylib.pdf.PdfGenerater;
import com.cysyz.mylib.pdf.support.BaseFontType;
import com.cysyz.mylib.pdf.support.FieldConfig;
import com.cysyz.mylib.pdf.support.OutputFileNameGenerater;
import com.cysyz.mylib.pdf.support.PdfGeneraterWithTemplateAllInOnePdf;
import com.cysyz.mylib.pdf.support.WithTemplatePdfgenerter;
import com.cysyz.mylib.utils.myassert.MyAssert;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.AcroFields.Item;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

public class PdfGenerateImpl implements PdfGenerater {
	private WithTemplatePdfgenerter pdfgernaterWithTemplate;

	public PdfGenerateImpl(WithTemplatePdfgenerter pdfgernaterWithTemplate) {
		this.pdfgernaterWithTemplate = pdfgernaterWithTemplate;
	}

	@Override
	public void generate(String templateFileAbsolutePath,
			OutputFileNameGenerater outputFileNameGenerater,
			List<List<FieldConfig>> fieldConfigs) throws FileNotFoundException{
		
		MyAssert.hasText(templateFileAbsolutePath, "模板文件的路径为空");
		MyAssert.notNull(outputFileNameGenerater);
		MyAssert.notNull(fieldConfigs);

		ByteArrayOutputStream[] afterReplacedPdfBytes = getAfterReplacedTemplateFileBytes(
				templateFileAbsolutePath, fieldConfigs);
		pdfgernaterWithTemplate.generatePdf(outputFileNameGenerater,
				afterReplacedPdfBytes, fieldConfigs);
	}

	private ByteArrayOutputStream[] getAfterReplacedTemplateFileBytes(
			String templateFileAbsolutePath,
			List<List<FieldConfig>> fieldConfigsList) {
		ByteArrayOutputStream[] afterReplacedPdfBytes = new ByteArrayOutputStream[fieldConfigsList
				.size()];
		List<String> notAssignedPlaceHolders = new ArrayList<String>();
		int i = 0;
		for (List<FieldConfig> fieldConfigs : fieldConfigsList) {
			afterReplacedPdfBytes[i] = new ByteArrayOutputStream();
			PdfReader templateReader = null;
			PdfStamper pdfStamper = null;
			try {
				templateReader = new PdfReader(templateFileAbsolutePath);
				pdfStamper = new PdfStamper(templateReader,
						new BufferedOutputStream(afterReplacedPdfBytes[i]));
				AcroFields tempalteFields = pdfStamper.getAcroFields();
				Set<Entry<String, Item>> templateFieldMapEntry = tempalteFields
						.getFields().entrySet();
				for (Entry<String, Item> entry : templateFieldMapEntry) {
					String fieldNameInTemplate = entry.getKey();
					boolean isFind = false;
					for (FieldConfig fc : fieldConfigs) {
						if (fc.getName().equals(fieldNameInTemplate)) {
							if (!MyAssert.isNullOrEmpty(fc.getTextfont())) {
								String[] textfont = fc.getTextfont().split(":");
								tempalteFields.setFieldProperty(fieldNameInTemplate,
										"textfont", BaseFont.createFont(textfont[0],
												textfont[1], BaseFont.EMBEDDED), null);
							}
							
							if (!MyAssert.isNullOrEmpty(fc.getFontsize())) {
								tempalteFields.setFieldProperty(fieldNameInTemplate,
										"textsize", fc.getFontsize(), null);
							}
							tempalteFields.setField(fieldNameInTemplate,
									fc.getValue());
							isFind = true;
							break;
						}
					}
					if (!isFind) {
						notAssignedPlaceHolders.add(fieldNameInTemplate);
					}
				}

				if (!notAssignedPlaceHolders.isEmpty()) {
					throw new RuntimeException(
							"模板文件中存在缺少对应替换值的占位符:"
									+ Arrays.toString(notAssignedPlaceHolders
											.toArray()));
				}
				pdfStamper.setFormFlattening(true);

			} catch (IOException | DocumentException ex) {
				throw new RuntimeException(ex);
			} finally {
				if (pdfStamper != null) {
					try {
						pdfStamper.close();
					} catch (DocumentException | IOException ex) {
						throw new RuntimeException(ex);
					}
				}
			}
			i++;
		}

		return afterReplacedPdfBytes;
	}

	public static void main(String[] args) {
		String templateFileAbsolutePath = "D:\\Desktop\\SkillSheet_崔130412 - 副本11.pdf";

		PdfGenerater pdfGenerateTool = new PdfGenerateImpl(new PdfGeneraterWithTemplateAllInOnePdf());
		List<List<FieldConfig>> fieldConfigs = new ArrayList<List<FieldConfig>>();
		List<FieldConfig> configs = new ArrayList<FieldConfig>();
		List<FieldConfig> configs1 = new ArrayList<FieldConfig>();
		List<FieldConfig> configs2 = new ArrayList<FieldConfig>();
		fieldConfigs.add(configs);
		fieldConfigs.add(configs1);
		fieldConfigs.add(configs2);
		configs2.add(new FieldConfig("school", "延边san中", BaseFontType.CHINESE, 8f));
		configs2.add(new FieldConfig("lang", "中文", BaseFontType.CHINESE, 9f));
		configs2.add(new FieldConfig("address", "双阳小区", BaseFontType.CHINESE, 12f));
		configs1.add(new FieldConfig("school", "延边一中", BaseFontType.CHINESE, 8f));
		configs1.add(new FieldConfig("lang", "中文", BaseFontType.CHINESE, 9f));
		configs1.add(new FieldConfig("address", "双阳小区", BaseFontType.CHINESE, 12f));
		configs.add(new FieldConfig("school", "延边二中", BaseFontType.CHINESE, 12f));
		configs.add(new FieldConfig("lang", "中文", BaseFontType.CHINESE, 12f));
		configs.add(new FieldConfig("address", "双阳小区", BaseFontType.CHINESE, 12f));
		try {
			pdfGenerateTool.generate(templateFileAbsolutePath, new OutputFileNameGenerater() {
				
				@Override
				public String generate(List<FieldConfig> list) {
					return "D:\\Desktop\\SkillSheet_崔130412 - 副本11" + list.get(0).getValue() + ".pdf";
				}
			}, fieldConfigs);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
}
